//从字典方法copy来的当做一个函数
function toStringFN(item){ //形参item就等同于key意思
    if(item === null){ //如果传入的key是null
        return ""
    }else if(item === undefined){ //如果传入的是undefined
        return "Undefined"
    }else if(typeof item === "string" || item instanceof String){ //如果传入的是与字符串有关的
        return `${item}`
    }
    //当然这个方法不算完美，因为有些对象名可能天生带有_id，所以可以生成一个非常复杂的独一无二的id识别码来避免这种情况
    if(item["_id"]){ //判断是否是被我们改造过的重名对象，这行代码替换掉了下面的set中注释掉的更新tablekey
        return item.toString() + item["_id"]
    }
    //如果以上情况都不是
    return item.toString()
}

//哈希函数
function loseloseHASHCode(key){ //将key转换成string，但是这样也依旧会算出相同的数，所以还需要再借助分离链接法
    if(typeof key === "number"){
        return key
    }
    let tablekey = toStringFN(key)
    let hashCode = 0
    //hash算法非常多，这里用一种遍历其中每一个字符，然后累加每一个字符的字符编码charCodeAt
    for(let i = 0; i < tablekey.length; i++){
        hashCode += tablekey.charCodeAt(i)
    }
    return hashCode % 37 //质数求余，除以任意一个质数取余，将取得的余数作为key，
    //密码学中非常难生成所有质数，因为质数无法用通项公式生成，所以用质数比较难被破解
}